package com.cetccloud.ap.config.route;

import com.cetccloud.ap.controller.model.req.HttpReq;
import com.cetccloud.ap.proxy.coord.Coord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.server.*;
import reactor.core.publisher.Mono;

import java.time.Duration;

/**
 * @ClassName RouteConfig
 * @Description TODO
 * @Author superz
 * @Date 2021/4/11 10:20
 * @Version 1.0
 **/
@Slf4j
//@Configuration
public class RouteConfig {

    @Autowired
    private Coord httpCoord;

    @Bean
    public RouterFunction<ServerResponse> routes() {
        HandlerFunction<ServerResponse> httpProxyFunction =
                request -> {
                    // 域内调用：等待结果“响应”并设置超时时间
                    HttpReq httpReq = new HttpReq();
                    httpReq.setDestZoneId("func3 req");
                    Mono<String> mono = WebClient.builder()
                            .exchangeStrategies(ExchangeStrategies.builder()
                                    .codecs(clientCodecConfigurer -> clientCodecConfigurer.
                                            defaultCodecs().maxInMemorySize(10*1024*1024))
                                    .build())// 除了使用create快速生成 外还可以使用builder创建
                            .baseUrl("http://127.0.0.1:8082/proxy/test").build()
                            .post().body(Mono.just(httpReq), HttpReq.class)  // 将info body 写入 proxy请求的body中
                            .retrieve()
                            .bodyToMono(String.class)
                            .timeout(Duration.ofMillis(3000));
                    mono.subscribe(v -> log.info(v));

                    // 跨域调用：等待结果“回调”并设置超时时间
                    return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(
                            Mono.create(sink -> httpCoord.registerSink("test", sink)).timeout(Duration.ofSeconds(10)), Object.class);
                };

        // antpath风格 ?：任何单字符，*：0或任意数量字符，**：0或多个目录

//        HandlerFunction<ServerResponse> dateFunction =
//                request -> ServerResponse.ok().contentType(MediaType.TEXT_PLAIN).body(
//                        Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);

        return RouterFunctions.route(RequestPredicates.method(HttpMethod.GET).and(RequestPredicates.path("/proxy/http/**")), httpProxyFunction)
//                        .andRoute(RequestPredicates.GET("/date"), dateFunction)
                .filter((request, next) -> {
                    log.info("filter: " + request.requestPath().pathWithinApplication().value());
                    return next.handle(request);
                });
    }
}
